/**
  ******************************************************************************
  * File Name          : weight.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "route.h"

TaskHandle_t xRoute_485_Thd = NULL;
StaticTask_t xRoute_485_Tcb;
StackType_t  xRoute_485_Stk[ROUTE_485_STACK_SIZE];

/* 485链路接收 */
QueueHandle_t Route_485RxLink_Qhd = NULL;
static StaticQueue_t route_485_rx_link_stru;
static uint8_t       route_485_rx_link_area[ROUTE_485RXLINK_QUE_LENGTH * ROUTE_485RXLINK_QUE_ITEMSIZE];

/* 485 接收消息队列 */
Route_PayloadType Route_485_rx_link_isr;
Route_PayloadType Route_485_rx_link_bck;
static Route_PayloadType route_evew_to_485_bck;

static void route_485_cycle(void)
{
  static uint8_t cycle = 0;
  static uint8_t addr = 0;

route_485_cycle_start:
  
  switch(cycle)
  {
    case 0:
      cycle++;

      if(Route_DeviceList.lx[addr].did[0] == 'L')
      {
        Route_lx_485_cycle(addr);
        return;
      }
      
    case 1:
      cycle++;
      if(Route_DeviceList.cf[addr].did[0] == 'C')
      {
        Route_cf_485_cycle(addr);
        return;
      }
      
    case 2:
      cycle++;
      if(Route_DeviceList.xc[addr].did[0] == 'X')
      {
        Route_xc_485_cycle(addr);
        return;
      }
      
    default:
      cycle = 0;
      if(addr++ >= ROUTE_DEVICE_MAXNUM-1)
      {
        addr = 0;
        return;
      }
      goto route_485_cycle_start;
  }
}

static void route_485_burst(Route_PayloadType *rtpl)
{
  uint8_t err;
  
  if((rtpl == NULL) && \
     (rtpl->trans_dir != ROUTE_TRSDIR_NET_TO_SUBDEV) && \
     (rtpl->trans_dir != ROUTE_TRSDIR_LOCAL_TO_SUBDEV))
  {
    return;
  }
  
  switch(rtpl->dev_type)
  {
    case RT_DV_UN:
      RS485_LinkSend(rtpl);
      break;
    
    case RT_DV_LX:
      Route_lx_485_burst(rtpl);
      break;
    
    case RT_DV_CF:
      Route_cf_485_burst(rtpl);
      break;
    
    case RT_DV_XC:
      Route_xc_485_burst(rtpl);
      break;
    
    default:
      err = 1;
      return;
  }
  
  if(err != 0)
  {
    return;
  }
}

void Route_485_broadtime(void)
{
  Route_PayloadType *proute = NULL;
	
  proute = pvPortMalloc(sizeof(Route_PayloadType));
  if(proute != NULL)
  {
    memset(proute, 0, sizeof(Route_PayloadType));
    
    proute->dev_addr  = 0xFEu;
    proute->dev_type  = RT_DV_UN;
    proute->trans_dir = ROUTE_TRSDIR_LOCAL_TO_SUBDEV,
    proute->pl_type   = ROUTE_PLTYP_UN_BCTIME,
    proute->pl_len    = 3;
    
    Sys_GetDataTime(&Sys_Runtime);
    
    proute->payload[0] = Sys_Runtime.hour;
    proute->payload[1] = Sys_Runtime.minute;
    proute->payload[2] = Sys_Runtime.second;
    
    if(Route_EvewTo485_Qhd != NULL)
    {
      xQueueSend(Route_EvewTo485_Qhd, proute, 0);
    }
  }
  
  vPortFree(proute);
}

void vRoute_485_Task(void * pvParameters)
{
  Route_485RxLink_Qhd = xQueueCreateStatic(ROUTE_485RXLINK_QUE_LENGTH, ROUTE_485RXLINK_QUE_ITEMSIZE,
	                                         route_485_rx_link_area, &route_485_rx_link_stru);
  RS485_BspInit();

  while(1)
	{
    route_485_cycle();
    
    vTaskDelay(20);
    
    if(xQueueReceive(Route_EvewTo485_Qhd, &route_evew_to_485_bck, 230) == pdTRUE)
    {
      route_485_burst(&route_evew_to_485_bck);
    }
  }
}
